import fs from 'fs';

// OPUS配置到帧大小的映射
const OPUS_CONFIG_TO_FRAME_SIZE = {
    0: 40,    // 2.5ms
    1: 80,    // 5ms
    2: 160,   // 10ms
    3: 320,   // 20ms
    4: 640,   // 40ms
    5: 960,   // 60ms
    6: 1280,  // 80ms
    7: 1920,  // 100ms
    8: 2560,  // 120ms
    9: 3840,  // 150ms
    10: 5120, // 160ms
    11: 2880, // 180ms (这个值很奇怪，不在标准OPUS配置中)
    12: 5760, // 200ms
    13: 7680, // 240ms
    14: 11520, // 480ms
    15: 23040, // 960ms
};

function analyzeOpusFrame(buffer) {
    console.log('=== 详细OPUS帧分析 ===');
    console.log(`帧大小: ${buffer.length} 字节`);
    console.log(`前32字节: ${buffer.slice(0, Math.min(32, buffer.length)).toString('hex')}`);
    
    if (buffer.length < 1) {
        console.log('❌ 帧数据太短');
        return;
    }
    
    // 解析TOC字节
    const toc = buffer[0];
    const config = (toc >> 3) & 0x1F;
    const stereo = (toc >> 2) & 0x01;
    const frameType = toc & 0x3;
    
    console.log(`TOC字节: 0x${toc.toString(16).padStart(2, '0')} (${toc})`);
    console.log(`配置: ${config}`);
    console.log(`立体声: ${stereo ? '是' : '否'}`);
    console.log(`帧类型: ${frameType}`);
    
    // 检查配置是否在标准范围内
    if (config in OPUS_CONFIG_TO_FRAME_SIZE) {
        const frameSize = OPUS_CONFIG_TO_FRAME_SIZE[config];
        const frameMs = (frameSize * 1000) / 16000;
        console.log(`对应帧大小: ${frameSize} 样本 (${frameMs}ms)`);
        
        if (config === 11) {
            console.log('⚠️  警告: config 11 (180ms) 不是标准OPUS配置！');
            console.log('   这可能表示OPUS编码器配置有问题');
        }
    } else {
        console.log(`❌ 未知配置: ${config}`);
    }
    
    // 分析帧类型
    const frameTypeNames = ['单帧', '2.5ms帧', '5ms帧', '10ms/20ms/40ms/60ms帧'];
    console.log(`帧类型: ${frameType} (${frameTypeNames[frameType] || '未知'})`);
    
    // 检查数据模式
    const uniqueBytes = new Set(buffer);
    console.log(`唯一字节数: ${uniqueBytes.size}/${buffer.length}`);
    
    if (uniqueBytes.size < 10) {
        console.log('⚠️  警告: 数据多样性很低，可能是无效数据');
    }
    
    // 检查是否有明显的模式
    const firstByte = buffer[0];
    const sameBytes = buffer.filter(b => b === firstByte).length;
    const sameRatio = sameBytes / buffer.length;
    
    if (sameRatio > 0.8) {
        console.log(`⚠️  警告: ${(sameRatio * 100).toFixed(1)}% 的字节都是相同的，可能是无效数据`);
    }
    
    return {
        config,
        frameType,
        stereo,
        frameSize: OPUS_CONFIG_TO_FRAME_SIZE[config] || 'unknown',
        isValid: uniqueBytes.size >= 10 && sameRatio < 0.8
    };
}

function analyzeOpusFile(filePath) {
    try {
        console.log(`\n=== 分析OPUS文件: ${filePath} ===`);
        const data = fs.readFileSync(filePath);
        
        // 检查文件头
        if (data.length < 25) {
            console.log('❌ 文件太小');
            return;
        }
        
        const opusHead = data.slice(0, 8).toString('ascii');
        if (opusHead !== 'OpusHead') {
            console.log('❌ 不是有效的OPUS文件头');
            return;
        }
        
        // 解析文件头信息
        const version = data[8];
        const channels = data[9];
        const preSkip = data.readUInt16LE(10);
        const sampleRate = data.readUInt32LE(12);
        const outputGain = data.readUInt16LE(16);
        const channelMapping = data[18];
        const frameSize = data.readUInt16LE(19);
        const totalFrames = data.readUInt32LE(21);
        
        console.log(`OPUS文件版本: ${version}`);
        console.log(`通道数: ${channels}`);
        console.log(`预跳过样本数: ${preSkip}`);
        console.log(`采样率: ${sampleRate}Hz`);
        console.log(`输出增益: ${outputGain}`);
        console.log(`通道映射: ${channelMapping}`);
        console.log(`帧大小: ${frameSize}`);
        console.log(`总帧数: ${totalFrames}`);
        
        // 分析前几个OPUS帧
        let offset = 25;
        const framesToAnalyze = Math.min(5, totalFrames);
        let configCounts = {};
        let validFrames = 0;
        
        console.log(`\n=== 分析前 ${framesToAnalyze} 个OPUS帧 ===`);
        for (let i = 0; i < framesToAnalyze; i++) {
            if (offset + 4 > data.length) break;
            
            const frameLength = data.readUInt32LE(offset);
            offset += 4;
            
            if (offset + frameLength > data.length) break;
            
            const frameData = data.slice(offset, offset + frameLength);
            console.log(`\n--- 帧 ${i + 1} ---`);
            
            const analysis = analyzeOpusFrame(frameData);
            if (analysis) {
                configCounts[analysis.config] = (configCounts[analysis.config] || 0) + 1;
                if (analysis.isValid) validFrames++;
            }
            
            offset += frameLength;
        }
        
        console.log(`\n=== 分析总结 ===`);
        console.log(`有效帧数: ${validFrames}/${framesToAnalyze}`);
        console.log(`配置分布:`, configCounts);
        
        if (configCounts[11]) {
            console.log('\n⚠️  发现config 11帧，这可能是OPUS编码器配置问题');
            console.log('建议检查ESP32的OPUS编码器配置');
        }
        
    } catch (error) {
        console.error('分析失败:', error.message);
    }
}

// 主函数
function main() {
    const args = process.argv.slice(2);
    
    if (args.length === 0) {
        console.log('用法: node analyze_opus_detailed.js <opus文件路径>');
        return;
    }
    
    const filePath = args[0];
    if (!fs.existsSync(filePath)) {
        console.log('文件不存在:', filePath);
        return;
    }
    
    analyzeOpusFile(filePath);
}

main();
